package com.mzj.eagle.util;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisUtils {

	private static JedisPool jedisPool = null;  
	  
    private JedisUtils() {  
  
    }  
      
    //写成静态代码块形式，只加载一次，节省资源  
    static {  
        String host = PropertiesUtils.getProperty("redis.host");  
        String port = PropertiesUtils.getProperty("redis.port");  
        String pass = PropertiesUtils.getProperty("redis.pass");  
        String timeout = PropertiesUtils.getProperty("redis.timeout");  
        String maxIdle = PropertiesUtils.getProperty("redis.maxIdle");  
        String maxTotal = PropertiesUtils.getProperty("redis.maxTotal");  
        String maxWaitMillis = PropertiesUtils.getProperty("redis.maxWaitMillis");  
        String testOnBorrow = PropertiesUtils.getProperty("redis.testOnBorrow");  
  
        JedisPoolConfig config = new JedisPoolConfig();  
        //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；  
        //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。  
        config.setMaxTotal(Integer.parseInt(maxTotal.trim()));  
        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。  
        config.setMaxIdle(Integer.parseInt(maxIdle.trim()));  
        //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；  
      //Idle时进行连接扫描
        config.setTestWhileIdle(true);
        //表示idle object evitor两次扫描之间要sleep的毫秒数
        config.setTimeBetweenEvictionRunsMillis(30000);
        //表示idle object evitor每次扫描的最多的对象数
        config.setNumTestsPerEvictionRun(10);
        config.setMaxWaitMillis(Long.parseLong(maxWaitMillis.trim()));  
        //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；  
        config.setTestOnBorrow(Boolean.valueOf(testOnBorrow.trim()));  
  
        jedisPool = new JedisPool(config, host, Integer.parseInt(port.trim()), Integer.parseInt(timeout.trim()), pass);  
    }  
  
    /** 
     * 从jedis连接池中获取获取jedis对象 
     * 
     * @return 
     */  
    private Jedis getJedis() {  
        return jedisPool.getResource();  
    }  
  
    private static final JedisUtils jedisUtil = new JedisUtils();  
  
    /** 
     * 获取JedisUtil实例 
     * 
     * @return 
     */  
    public static JedisUtils getInstance() {  
        return jedisUtil;  
    }  
  
    /** 
     * 回收jedis(放到finally中) 
     * 
     * @param jedis 
     */  
    private void returnJedis(Jedis jedis) {  
        if (null != jedis && null != jedisPool) {  
            jedisPool.returnResource(jedis);  
        }  
    }  
  
    /** 
     * 销毁连接(放到catch中) 
     * 
     * @param jedis 
     */  
    private static void returnBrokenResource(Jedis jedis) {  
        if (null != jedis && null != jedisPool) {  
            jedisPool.returnResource(jedis);  
        }  
    }  
    
    /** 
     * 添加sorted set 
     * @param key 
     * @param value 
     * @param score 
     */  
    public void set(int db,int param,String key, String value) {  
        Jedis jedis = getJedis();  
        jedis.select(db);
        jedis.set(key+"_"+param, value);
        jedis.expire(key, 60 * 1000);
        returnJedis(jedis);  
    }
    
    /** 
     * @param key 
     * @param value 
     * @param score 
     */  
    public void set(int db,int param,byte[] key, byte[] value) {  
        Jedis jedis = getJedis();  
        jedis.select(db);
        String tempKey = new String(key, UTF_8)+"_"+param;
        jedis.set(tempKey.getBytes(), value);
        jedis.expire(key, 60 * 1000);
        returnJedis(jedis);  
    }
  
    public void returnResource(Jedis jedis, boolean isBroken) {  
        if (jedis == null)  
            return;  
        if (isBroken)  
            jedisPool.returnBrokenResource(jedis);  
        else  
            jedisPool.returnResource(jedis);  
    }  
      
    /** 
     * 是否存在KEY 
     * @param key 
     * @return 
     */  
    public boolean exists(int db, int param, String key) {  
        Jedis jedis = getJedis();  
        jedis.select(db);
        boolean exists = jedis.exists(key+"_"+param);  
        returnJedis(jedis);  
        return exists;  
    }  
  
    /** 
     * 是否存在KEY 
     * @param key 
     * @return 
     */  
    public boolean exists(int db, int param, byte[] key) {  
        Jedis jedis = getJedis();  
        jedis.select(db);
        String tempKey = new String(key, UTF_8)+"_"+param;
        boolean exists = jedis.exists(tempKey);  
        returnJedis(jedis);  
        return exists;  
    }  
  
    /** 
     * 删除失效时间 
     * @param key 
     */  
    public void persist(String key) {  
        Jedis jedis = getJedis();  
        jedis.persist(key);  
        returnJedis(jedis);  
    }  
      
    /** 
     * 添加一个键值对，如果键存在不在添加，如果不存在，添加完成以后设置键的有效期 
     * @param key 
     * @param value 
     * @param timeOut 
     */  
    public void setnxWithTimeOut(String key,String value,int timeOut){  
        Jedis jedis = getJedis();  
        if(0!=jedis.setnx(key, value)){  
            jedis.expire(key, timeOut);  
        }  
        returnJedis(jedis);  
    }  
      
    /** 
     * 返回指定key序列值  
     * @param key 
     * @return 
     */  
    public long incr(String key){  
        Jedis jedis = getJedis();  
        long l = jedis.incr(key);  
        returnJedis(jedis);  
        return l;  
    }  
      
    /** 
     * 获取当前时间  
     * @return 秒 
     */  
    public long currentTimeSecond(){  
        Long l = 0l;  
        Jedis jedis = getJedis();  
        Object obj = jedis.eval("return redis.call('TIME')",0);  
        if(obj != null){  
            List<String> list = (List)obj;  
            l = Long.valueOf(list.get(0));  
        }  
        returnJedis(jedis);  
        return l;  
    }  
}
